package com.liang.security;


import com.liang.empty.ClientMsg;
import com.liang.empty.Result;
import com.liang.pojo.Authority;
import com.liang.pojo.Userz;
import com.liang.pojo.Userzandrolez;
import com.liang.service.AuthorityService;
import com.liang.service.UserzService;
import com.liang.service.UserzandrolezService;
import com.liang.utils.IpUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Aspect //说明当前对象时一个切面
@PropertySource(value = "classpath:resource.properties")
@Component
public class SecurityAopConfig {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private AuthorityService authorityService;

    @Autowired
    private UserzandrolezService userzandrolezService;



    //登录
    @Value("${user.login}")
    private String UserLoginRedisKey;

    //配置切点
    @Around("@annotation(com.liang.security.MySecurity)")
    public Object toLogin(ProceedingJoinPoint pjp) throws Throwable {
        //获取request和response
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        //请求头是否有
        if(request.getHeader("idconfig") == null  || request.getHeader("tokenconfig") == null ){
            return Result.buildFail( 888,"请登录");
        }
        //用户ID和token必须有，不然让登录
        String idconfig = request.getHeader("idconfig").toString();
        String tokenconfig = request.getHeader("tokenconfig").toString();
        //角色ID
        String compconfig = request.getHeader("compconfig").toString();

        if(idconfig.equals("error") || tokenconfig.equals("error")){
            return Result.buildFail( 888,"请登录");
        }




        ClientMsg clientMsg = IpUtil.getRequestMsg(request);
        //用户是电脑还是手机
//        if(clientMsg.getClientType().toUpperCase().equals("COMPUTER")){
//            return Result.buildFail( 666,"你没有执行权限");
//        }
        //查看token与request组合体是否和redis一致，不一致禁止访问
        String UserAddress = IpUtil.getTokenPassword(clientMsg,tokenconfig).toLowerCase();
        String RedisAddress = redisTemplate.opsForHash().get(UserLoginRedisKey,idconfig).toString().toLowerCase();
        if(!UserAddress.equals(RedisAddress)){
            return Result.buildFail( 888,"请登录");
        }

        // 获取目标方法上的注解
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        MySecurity mySecurity = method.getAnnotation(MySecurity.class);
        //获取注解上的值
        String methodx = mySecurity.methodx();
//        System.out.println(methodx);
        if(!methodx.equals("ordinary")){
            Map userRoleMap = new HashMap();
            userRoleMap.put("user_id",idconfig);
            userRoleMap.put("role_id",compconfig);
            List<Userzandrolez> userzandrolezs = userzandrolezService.selectList(userRoleMap);
            if(userzandrolezs.size() <= 0 ){
                return Result.buildFail( 666,"你没有执行权限");
            }
            Map authoritymap = new HashMap();
            authoritymap.put("au_roleId",compconfig);
            authoritymap.put("au_menuId",methodx);
            List<Authority> listx = authorityService.selectList(authoritymap);
            if(listx.size() <= 0 ){
                return Result.buildFail( 666,"你没有执行权限");
            }
            return  pjp.proceed();
        }



        //pjp.proceed为该方法的返回值
        return  pjp.proceed();
    }




    private  Map getParameter(String valueStr) {
        Map map = new HashMap<String, Object>();
        String[] keyValues = valueStr.split("&");
        for (int i = 0; i < keyValues.length; i++) {
            String key = keyValues[i].substring(0, keyValues[i].indexOf("="));
            String value = keyValues[i].substring(keyValues[i].indexOf("=") + 1);
            map.put(key, value);
        }
        return map;
    }



}
